<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>长列表</title>
  <style>
    #app {
      text-align: center;
    }

    img {
      width: 200px;
      height: 200px;
      padding: 20px;
    }
  </style>
</head>

<body>
  <div id="app"></div>
</body>
<script>
  const $app = document.getElementById('app')

  const oblazy = (imgs) => {
    // 兼容IE
    if (!IntersectionObserver) {
      $app.innerHTML = $app.innerHTML.replace(/data-src/g, 'src')
      return
    }
    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        const $img = entry.target
        if ($img.src) return
        if (entry.intersectionRatio > 0.5) {
          $img.src = $img.dataset.src
          delete $img.dataset.src
        }
      });
    }, {
      threshold: [0.5],
    });
    imgs.forEach(v => observer.observe(v))
  }

  const debounce = (func, wait) => {
    let timer = null
    return function (...args) {
      if (timer) clearTimeout(timer)
      timer = setTimeout(() => {
        func(...args)
      }, wait)
    }
  }

  const clientLazy = (imgs) => {
    const lazyLoad = () => {
      const windowHeight = document.documentElement.clientHeight
      imgs.forEach(($img, i) => {
        if ($img.dataset.src && $img.getBoundingClientRect().bottom >= 0 && windowHeight > $img.getBoundingClientRect().top) {
          $img.src = $img.dataset.src
          delete $img.dataset.src
        }
      })
    }
    lazyLoad()
    document.addEventListener('scroll', debounce(lazyLoad, 200))
  }

  fetch('https://api.apiopen.top/getJoke?page=1&count=50&type=image')
    .then(res => res.json())
    .then(res => {
      let listDom = res.result.map(v => `<div><img class="lazy" data-src="${v.images}" /></div>`).join('')
      $app.innerHTML = listDom

      const imgs = document.querySelectorAll('.lazy')
      oblazy(imgs)
      // clientLazy(imgs)
    })

</script>

</html>